//ChatWidget.cpp
#include "ChatWidget.h"
#include <QVBoxLayout>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDateTime>
#include <QDebug>
#include <QTimer>
#include <QRegularExpression>

ChatWidget::ChatWidget(QWidget *parent) : QWidget(parent),
    m_chatHistory(new QTextEdit(this)),
    m_input(new QLineEdit(this)),
    m_sendButton(new QPushButton("发送", this)),
    m_switchToInterventionButton(new QPushButton("切换到智能干预", this)),
    m_networkManager(new QNetworkAccessManager(this)),
    m_apiKey("sk-4be6cf99ddf14c9aaaa16e1d8a7f79dd"), // 初始化对话模式API密钥
    m_apiType("qwen"),
    m_dbManager(nullptr),
    m_currentReply(nullptr),
    m_isInterventionMode(false), // 初始化为非干预模式
    m_dialogApiKey("sk-4be6cf99ddf14c9aaaa16e1d8a7f79dd"), // 初始化对话模式API密钥
    m_interventionApiKey("sk-4be6cf99ddf14c9aaaa16e1d8a7f79dd") // 初始化干预模式API密钥
{
    m_chatHistory->setReadOnly(true);
    m_input->setPlaceholderText("在此输入提问...");

    // 布局
    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(m_chatHistory);

    QHBoxLayout *inputLayout = new QHBoxLayout();
    inputLayout->addWidget(m_input);
    inputLayout->addWidget(m_sendButton);
    layout->addLayout(inputLayout);

    // 新增：添加切换按钮到布局
    layout->addWidget(m_switchToInterventionButton);

    setLayout(layout);

    // 连接发送按钮
    connect(m_sendButton, &QPushButton::clicked, this, &ChatWidget::onSendClicked);

    // 连接回车键发送
    connect(m_input, &QLineEdit::returnPressed, this, &ChatWidget::onSendClicked);

    // 新增：连接切换按钮的点击信号
    connect(m_switchToInterventionButton, &QPushButton::clicked,
            this, &ChatWidget::onSwitchToInterventionClicked);

    // 开局自动测试API连接
    QTimer::singleShot(500, this, &ChatWidget::testApiConnection);
}

// 新增：处理切换按钮点击的槽函数
void ChatWidget::onSwitchToInterventionClicked() {
    // 切换模式
    m_isInterventionMode = !m_isInterventionMode;

    if (m_isInterventionMode) {
        // 切换到智能干预模式
        m_switchToInterventionButton->setText("切换到智能对话");
        m_apiType = "qwen"; // 使用同样的API类型，但不同的密钥

        // 保存当前对话模式的API密钥
        if (m_dialogApiKey.isEmpty()) {
            m_dialogApiKey = m_apiKey;
        }

        // 设置干预模式的API密钥
        m_apiKey = m_interventionApiKey;
    } else {
        // 切换回智能对话模式
        m_switchToInterventionButton->setText("切换到智能干预");
        m_apiType = "qwen"; // 保持API类型不变

        // 恢复对话模式的API密钥
        if (!m_dialogApiKey.isEmpty()) {
            m_apiKey = m_dialogApiKey;
        }
    }

    // 清空聊天历史并提示用户已切换模式
    m_chatHistory->clear();
    m_conversationHistory.clear();

    // 测试API连接
    testApiConnection();

    // 发射切换模式信号
    emit switchToInterventionModule();
}

void ChatWidget::setDatabaseManager(DatabaseManager *dbManager) {
    m_dbManager = dbManager;
}

void ChatWidget::setApiKey(const QString &apiKey) {
    m_apiKey = apiKey;

    // 如果当前不是干预模式，也保存为对话模式的API密钥
    if (!m_isInterventionMode) {
        m_dialogApiKey = apiKey;
    }
}

void ChatWidget::setApiType(const QString &type) {
    m_apiType = type.toLower();
}

QNetworkRequest ChatWidget::createApiRequest() {
    QNetworkRequest request;

    if (m_isInterventionMode) {
        request.setUrl(QUrl("http://127.0.0.1:8000/intervene/"));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    }
    else if (m_apiType == "openai") {
        request.setUrl(QUrl("https://api.openai.com/v1/chat/completions"));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        request.setRawHeader("Authorization", QString("Bearer %1").arg(m_apiKey).toUtf8());
    }
    else if (m_apiType == "qwen") {
        // 通义千问API
        request.setUrl(QUrl("https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        request.setRawHeader("Authorization", QString("Bearer %1").arg(m_apiKey).toUtf8());
        // 启用SSE
        request.setRawHeader("Accept", "text/event-stream");
        request.setRawHeader("X-DashScope-SSE", "enable");
    }

    return request;
}

QByteArray ChatWidget::createRequestBody() {
    QJsonObject json;

    if (m_isInterventionMode) {
        const QString& lastMessage = m_conversationHistory.last().second;

        // 设置 JSON 格式为 {"text": "最后一条消息内容"}
        json["text"] = lastMessage;
    }
    else if (m_apiType == "openai") {
        // OpenAI格式
        QJsonArray messages;

        int startIdx = qMax(0, m_conversationHistory.size() - 10);
        for (int i = startIdx; i < m_conversationHistory.size(); i++) {
            QJsonObject message;
            message["role"] = m_conversationHistory[i].first;
            message["content"] = m_conversationHistory[i].second;
            messages.append(message);
        }

        json["model"] = "gpt-3.5-turbo";
        json["messages"] = messages;
    }
    else if (m_apiType == "qwen") {
        // 通义千问格式
        QJsonArray messages;

        int startIdx = qMax(0, m_conversationHistory.size() - 10);
        for (int i = startIdx; i < m_conversationHistory.size(); i++) {
            QJsonObject message;
            message["role"] = m_conversationHistory[i].first;
            message["content"] = m_conversationHistory[i].second;
            messages.append(message);
        }

        QJsonObject input;
        input["messages"] = messages;

        QJsonObject parameters;
        parameters["result_format"] = "message";
        parameters["temperature"] = 0.7;
        parameters["max_tokens"] = 1500;

        json["model"] = "qwen-turbo"; // 使用可用的模型
        json["input"] = input;
        json["parameters"] = parameters;
    }

    return QJsonDocument(json).toJson();
}

QString ChatWidget::parseApiResponse(const QByteArray &response) {
    QJsonDocument doc = QJsonDocument::fromJson(response);
    QString answer;

    if (!doc.isObject()) {
        return QString();
    }

    QJsonObject obj = doc.object();

    if (m_apiType == "openai") {
        // OpenAI响应格式
        if (obj.contains("choices") && obj["choices"].isArray() && !obj["choices"].toArray().isEmpty()) {
            answer = obj["choices"].toArray()[0].toObject()["message"].toObject()["content"].toString();
        }
    }
    else if (m_apiType == "qwen") {
        // 通义千问响应格式
        if (obj.contains("output") && obj["output"].isObject()) {
            QJsonObject output = obj["output"].toObject();
            if (output.contains("choices") && output["choices"].isArray() && !output["choices"].toArray().isEmpty()) {
                QJsonObject choice = output["choices"].toArray()[0].toObject();
                if (choice.contains("message") && choice["message"].isObject()) {
                    answer = choice["message"].toObject()["content"].toString();
                }
            }
        }
    }

    return answer;
}

QString ChatWidget::parseSSEResponse(const QByteArray &response) {
    // 解析SSE格式的响应
    // 格式: "data:{json}\n\n"
    QString responseStr = QString::fromUtf8(response);
    QString dataStr;

    // 查找data:后面的JSON部分
    QRegularExpression dataRegex("data:(\\{.*\\})");
    QRegularExpressionMatch match = dataRegex.match(responseStr);

    if (match.hasMatch()) {
        dataStr = match.captured(1);
        QJsonDocument doc = QJsonDocument::fromJson(dataStr.toUtf8());

        if (doc.isObject()) {
            QJsonObject obj = doc.object();

            if (obj.contains("output") && obj["output"].isObject()) {
                QJsonObject output = obj["output"].toObject();
                if (output.contains("choices") && output["choices"].isArray() && !output["choices"].toArray().isEmpty()) {
                    QJsonObject choice = output["choices"].toArray()[0].toObject();
                    if (choice.contains("message") && choice["message"].isObject()) {
                        return choice["message"].toObject()["content"].toString();
                    }
                }
            }
        }
    }

    return QString();
}

void ChatWidget::onSendClicked() {
    QString question = m_input->text().trimmed();
    if (question.isEmpty()) return;

    // 清除多余的空行
    QTextCursor cursor = m_chatHistory->textCursor();
    cursor.movePosition(QTextCursor::End);

    // 如果不是第一条消息，确保只有一个空行
    if (!m_chatHistory->toPlainText().isEmpty()) {
        // 添加用户提问，使用insertHtml而不是append来避免额外的换行
        m_chatHistory->textCursor().insertHtml(QString("<b>用户:</b> %1<br>").arg(question));
    } else {
        // 第一条消息
        m_chatHistory->textCursor().insertHtml(QString("<b>用户:</b> %1<br>").arg(question));
    }

    // 存储用户问题到对话历史
    m_conversationHistory.append(qMakePair(QString("user"), question));

    // 发射信号并记录到数据库
    emit userQuestionAsked(question);

    // 如果数据库管理器存在，记录聊天事件
    if (m_dbManager) {
        m_dbManager->logChatEvent(question, "user");
    }

    m_input->clear();

    // 准备请求API
    if (m_apiKey.isEmpty()) {
        m_chatHistory->textCursor().insertHtml("<font color='red'><b>错误:</b> 未提供API Key</font><br>");
        return;
    }

    QNetworkRequest request = createApiRequest();
    QByteArray requestBody = createRequestBody();

    // 输出请求内容用于调试
    qDebug() << "API请求内容:" << requestBody;
    qDebug() << "API请求URL:" << request.url().toString();
    qDebug() << "API请求头:";
    for (const QByteArray& header : request.rawHeaderList()) {
        qDebug() << header << ":" << request.rawHeader(header);
    }

    // 发送POST请求
    m_currentReply = m_networkManager->post(request, requestBody);
    m_currentAnswer.clear(); // 清空当前累积的回答

    // 连接readyRead信号以处理流式响应 (mrr: 流式响应会出现乱序和重复，就统一使用响应结束后解析了)
    // connect(m_currentReply, &QNetworkReply::readyRead, this, &ChatWidget::onReadyRead);
    connect(m_currentReply, &QNetworkReply::finished, this, &ChatWidget::onReplyFinished);
}

void ChatWidget::onReadyRead() {
    if (!m_currentReply) return;

    // 读取可用数据
    QByteArray data = m_currentReply->readAll();

    // 处理SSE格式的数据
    QStringList events = QString::fromUtf8(data).split("\n\n", Qt::SkipEmptyParts);
    bool updated = false;

    for (const QString &event : events) {
        if (event.contains("data:")) {
            QRegularExpression dataRegex("data:(\\{.*\\})");
            QRegularExpressionMatch match = dataRegex.match(event);

            if (match.hasMatch()) {
                QString jsonStr = match.captured(1);
                QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());

                if (doc.isObject()) {
                    QJsonObject obj = doc.object();

                    if (obj.contains("output") && obj["output"].isObject()) {
                        QJsonObject output = obj["output"].toObject();
                        if (output.contains("choices") && output["choices"].isArray() && !output["choices"].toArray().isEmpty()) {
                            QJsonObject choice = output["choices"].toArray()[0].toObject();
                            if (choice.contains("message") && choice["message"].isObject()) {
                                QString content = choice["message"].toObject()["content"].toString();

                                // 更新累积的回答
                                m_currentAnswer += content;
                                updated = true;
                            }
                        }
                    }
                }
            }
        }
    }

    // 只有在内容更新时才更新UI
    if (updated) {
        // 查找并删除之前的回答行
        QTextCursor cursor = m_chatHistory->textCursor();
        cursor.movePosition(QTextCursor::End);

        // 向上搜索最后一个"助手:"
        QTextDocument *doc = m_chatHistory->document();
        QString text = doc->toPlainText();
        int lastAssistantPos = text.lastIndexOf("助手:");

        if (lastAssistantPos >= 0) {
            // 删除从"助手:"开始的所有内容
            cursor.setPosition(lastAssistantPos, QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
            cursor.removeSelectedText();

            // 添加新的回答（不添加额外的换行）
            m_chatHistory->textCursor().insertHtml(QString("<b>助手:</b> %1").arg(m_currentAnswer));
        } else {
            // 如果找不到"助手:"，直接添加新回答
            m_chatHistory->textCursor().insertHtml(QString("<b>助手:</b> %1").arg(m_currentAnswer));
        }
    }
}

void ChatWidget::onReplyFinished() {
    if (!m_currentReply) return;
    QString answer;

    if (m_currentReply->error() != QNetworkReply::NoError) {
        m_chatHistory->textCursor().insertHtml(QString("<font color='red'><b>API调用失败:</b> %1</font><br>").arg(m_currentReply->errorString()));

        // 输出详细错误信息
        QByteArray errorData = m_currentReply->readAll();
        qWarning() << "API错误详情:" << errorData;
        qWarning() << "错误代码:" << m_currentReply->error();
        qWarning() << "错误字符串:" << m_currentReply->errorString();
    }
    else if(m_isInterventionMode){
        QByteArray responseData = m_currentReply->readAll();

        qDebug() << "Fastapi完整响应:" << responseData;

        QJsonParseError parseError;
        QJsonDocument doc = QJsonDocument::fromJson(responseData, &parseError);

        if (parseError.error == QJsonParseError::NoError && doc.isObject()) {
            QJsonObject obj = doc.object();
            if (obj.contains("advice") && obj["advice"].isString()) {
                QString content = obj["advice"].toString();
                answer += content;

            }
        }
        qDebug()<< "FAST API answer" << answer;

        if (!answer.isEmpty()) {
            m_currentAnswer = answer;

            // 更新UI显示
            m_chatHistory->textCursor().insertHtml(QString("<b>助手:</b> %1<br>").arg(m_currentAnswer));
        } else {
            m_chatHistory->textCursor().insertHtml("<font color='red'>FASTAPI解析响应失败</font><br>");
        }

    }
    else if(m_currentAnswer.isEmpty()){
        QString answer;
        // 如果响应已经完成，但m_currentAnswer为空，尝试从完整响应中解析
        if (m_currentAnswer.isEmpty()) {
            if(!m_isInterventionMode){
                QByteArray responseData = m_currentReply->readAll();
                qDebug() << "API完整响应:" << responseData;

                // 尝试解析SSE格式的完整响应

                QStringList events = QString::fromUtf8(responseData).split("\n\n", Qt::SkipEmptyParts);

                for (const QString &event : events) {
                    QString eventAnswer = parseSSEResponse(event.toUtf8());
                    if (!eventAnswer.isEmpty()) {
                        answer = eventAnswer;
                    }
                }
            }
        }

        qDebug()<< "SSE_delay answer" << answer;

        if (!answer.isEmpty()) {
            m_currentAnswer = answer;

            // 更新UI显示
            m_chatHistory->textCursor().insertHtml(QString("<b>助手:</b> %1<br>").arg(m_currentAnswer));
        } else {
            m_chatHistory->textCursor().insertHtml("<font color='red'>API SSE解析响应失败</font><br>");
        }

    }

    // 如果成功获取到回答，存储到对话历史并记录到数据库
    if (!m_currentAnswer.isEmpty()) {
        // 存储回复到对话历史
        m_conversationHistory.append(qMakePair(QString("assistant"), m_currentAnswer));

        // 如果数据库管理器存在，记录回复
        if (m_dbManager) {
            m_dbManager->logChatEvent(m_currentAnswer, "assistant");
        }
    }

    // 清理
    m_currentReply->deleteLater();
    m_currentReply = nullptr;
}

void ChatWidget::testApiConnection() {
    m_chatHistory->textCursor().insertHtml("<b>正在测试API连接...</b><br>");

    QNetworkRequest request;

    if (m_isInterventionMode) {
        // 如果是智能干预模式，测试 FastAPI 的 /healthcheck
        request.setUrl(QUrl("http://127.0.0.1:8000/healthcheck"));  // 替换为你的 FastAPI 地址
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    }
    else if (m_apiType == "openai") {
        request.setUrl(QUrl("https://api.openai.com/v1/models"));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        request.setRawHeader("Authorization", QString("Bearer %1").arg(m_apiKey).toUtf8());
    }
    else if (m_apiType == "qwen" || m_apiType.isEmpty()) { // 默认使用通义千问API
        // 通义千问API测试端点
        request.setUrl(QUrl("https://dashscope.aliyuncs.com/api/v1/models"));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
        request.setRawHeader("Authorization", QString("Bearer %1").arg(m_apiKey).toUtf8());
    }

    // 确保URL有效
    if (!request.url().isValid()) {
        m_chatHistory->textCursor().insertHtml(QString("<font color='red'><b>API连接测试失败:</b> 无效的URL</font><br>"));
        return;
    }

    qDebug() << "API测试URL:" << request.url().toString();
    qDebug() << "API测试头:";
    for (const QByteArray& header : request.rawHeaderList()) {
        qDebug() << header << ":" << request.rawHeader(header);
    }

    QNetworkReply *reply = m_networkManager->get(request);
    connect(reply, &QNetworkReply::finished, [this, reply]() {
        if (reply->error() != QNetworkReply::NoError) {
            m_chatHistory->textCursor().insertHtml(QString("<font color='red'><b>API连接测试失败:</b> %1</font><br>").arg(reply->errorString()));
            QByteArray errorData = reply->readAll();
            qWarning() << "API测试错误详情:" << errorData;
            qWarning() << "错误代码:" << reply->error();
            qWarning() << "错误字符串:" << reply->errorString();
        } else {
            m_chatHistory->textCursor().insertHtml("<font color='green'><b>API连接测试成功!</b></font><br>");
            QByteArray responseData = reply->readAll();
            qDebug() << "API测试响应:" << responseData;

            // 显示当前模式
            if (m_isInterventionMode) {
                m_chatHistory->textCursor().insertHtml("<b>当前模式: 智能干预</b><br>");
            } else {
                m_chatHistory->textCursor().insertHtml("<b>当前模式: 智能对话</b><br>");
            }
        }
        reply->deleteLater();
    });
}
